package com.lcxw.hxzbapi.controller.appcontroller;

import com.alibaba.fastjson.JSONObject;
import com.lcxw.hxzbapi.entity.pojo.YwpdMember;
import com.lcxw.hxzbapi.entity.requestBean.LoginRequestParam;
import com.lcxw.hxzbapi.entity.response.Response;
import com.lcxw.hxzbapi.service.YwpdMemberService;
import com.lcxw.hxzbcommon.common.AesCBCUtil;
import com.lcxw.hxzbcommon.common.RedisUtils;
import com.lcxw.hxzbcommon.common.StringUtil;
import com.lcxw.hxzbcommon.entity.ErrorCode;
import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author lcwx
 */
@RestController
@RequestMapping("/api/user")
@CrossOrigin
@Validated
public class LoginController {

    private Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Resource
    RedisUtils redisUtils;

    @Resource
    YwpdMemberService ywpdMemberService;

    @PostMapping("/login")
    public Response login(@Valid @RequestBody LoginRequestParam loginParam) {

        logger.info("登录请求：{}", loginParam);

        //构造响应
        Response response = new Response();

        YwpdMember ywpdMember;

        String token;

        try {
            ywpdMember = ywpdMemberService.selectYwpdMemberByTelephone(loginParam.getTelephone());

            if (null == ywpdMember || !loginParam.getPassword().equals(ywpdMember.getPassword())) {
                logger.warn("手机号码为{}的用户不存在或密码错误，登录失败", loginParam.getTelephone());
                response.setCode(ErrorCode.INVALID_PARAM);
                response.setDesc("用户不存在或密码错误");
                return response;
            }

            if (1 == ywpdMember.getCancelled()) {
                return Response.common(logger, "user is cancelled.", ErrorCode.LOSE_EFFICACY,
                    "user is cancelled.", null);
            }

            //登录成功，更新用户登录信息，存到数据库
            ywpdMember.setLastLogIp(loginParam.getIp());
            ywpdMember.setLongitude(loginParam.getLongitude());
            ywpdMember.setLatitude(loginParam.getLatitude());
            ywpdMemberService.updateYwpdMember(ywpdMember);

            //构造token 使用userId和时间戳，生成唯一token
            String tokenKey =
                ywpdMember.getUserId() + ":" + Calendar.getInstance().getTimeInMillis();
            token = AesCBCUtil.getInstance().encrypt(tokenKey);

            //登录成功后，userId，和对应的token存到redis,保存10天，10天内免登陆
            redisUtils
                .string_set("uid:" + ywpdMember.getUserId() + ":token", token, 60 * 60 * 24 * 30);
            logger.info("userid 为 {} 登录成功,token为 : {}", ywpdMember.getUserId(), token);

        } catch (Exception e) {
            logger.warn("数据库操作失败，使用手机号码查询:{}", loginParam.getTelephone());
            response.setCode(ErrorCode.DB_OPERATE_FAIL);
            response.setDesc("数据库操作失败，请联系后台开发人员");
            return response;
        }

        Map<String, Object> data = new LinkedHashMap<>();
        data.put("userId", ywpdMember.getUserId());
        data.put("token", token);
        response.setCode(0);
        response.setDesc("success");
        response.setData(data);

        return response;
    }

    @PostMapping("/captchalogin")
    public Response captchaLogin(@RequestBody JSONObject requestParams) {
        String telephone = requestParams.getString("telephone");
        String captcha = requestParams.getString("captcha");
        String longitude = requestParams.getString("longitude");
        String latitude = requestParams.getString("latitude");
        logger.info("user {} login by captcha {}", telephone, captcha);
        Response response = new Response();

        if (StringUtil.isEmpty(telephone) || StringUtil.isEmpty(captcha)) {
            logger.warn("telephone {} or captcha {} is null", telephone, captcha);
            response.setCode(ErrorCode.PARAM_ERROR);
            response.setDesc("telephone or captcha must not be null");
            return response;
        }

        String captchaFromRedis = redisUtils.string_get("captchaSuccess:login" + telephone);
        if (StringUtil.isEmpty(captchaFromRedis) || !captcha.equals(captchaFromRedis)) {
            return Response.common(logger, "captcha is wrong or expire。", ErrorCode.INVALID_REQ,
                "captcha is wrong or expire。", null);
        }
        YwpdMember ywpdMember;
        String token;
        try {
            ywpdMember = ywpdMemberService.selectYwpdMemberByTelephone(telephone);
            if (null == ywpdMember) {
                return Response
                    .common(logger, "user with telephone {" + telephone + "} is not exist.",
                        ErrorCode.INVALID_PARAM, "user is not exist.", null);
            }

            if (1 == ywpdMember.getCancelled()) {
                return Response.common(logger, "user is cancelled.", ErrorCode.LOSE_EFFICACY,
                    "user is cancelled.", null);
            }

            //登录成功，更新用户登录信息，存到数据库
            ywpdMember.setLastLogIp(requestParams.getString("ip"));
            ywpdMember.setLongitude(longitude);
            ywpdMember.setLatitude(latitude);
            ywpdMemberService.updateYwpdMember(ywpdMember);

            //这个时候用户使用验证码登录成功，构造token 使用userId和时间戳，生成唯一token
            String tokenKey =
                ywpdMember.getUserId() + ":" + Calendar.getInstance().getTimeInMillis();
            token = AesCBCUtil.getInstance().encrypt(tokenKey);

            //登录成功后，userId，和对应的token存到redis
            redisUtils
                .string_set("uid:" + ywpdMember.getUserId() + ":token", token, 60 * 60 * 24 * 30);
            logger.info("userid 为 {} 登录成功,token为 : {}", ywpdMember.getUserId(), token);

        } catch (Exception e) {
            e.printStackTrace();
            logger.warn("数据库操作失败，使用手机号码查询:{}", telephone);
            response.setCode(ErrorCode.DB_OPERATE_FAIL);
            response.setDesc("数据库操作失败，请联系后台开发人员");
            return response;

        }

        Map<String, Object> data = new LinkedHashMap<>();
        data.put("userId", ywpdMember.getUserId());
        data.put("token", token);
        response.setCode(0);
        response.setDesc("success");
        response.setData(data);

        return response;

    }


}